﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace MAF.Windows
{
    /// <summary>
    /// 记事列表控件。
    /// </summary>
    public partial class MAFListView : UserControl
    {
        /// <summary>
        /// 构造方法
        /// </summary>
        public MAFListView()
        {
            InitializeComponent();

            this.BackColor = Color.LightGray;
            Items = new NoteListViewItemCollection(this);
            CheckedItems = new NoteListViewItemCollection(this);
            //Items.Add(new NoteListViewItem("很长很试字很长的测试字符很试字的测很长的测试字符很长的测试字符"));
        }

        /// <summary>
        /// 列表项集合
        /// </summary>
        public NoteListViewItemCollection Items { get; set; }

        /// <summary>
        /// 已勾选的列表项
        /// </summary>
        public NoteListViewItemCollection CheckedItems { get; set; }

        #region 列表项集合

        /// <summary>
        /// 列表项集合
        /// </summary>
        public class NoteListViewItemCollection
        {
            /// <summary>
            /// 记住由本集合增加的Controls
            /// </summary>
            private List<MAFListViewItem> _items = null;

            /// <summary>
            /// 构造方法
            /// </summary>
            public NoteListViewItemCollection(MAFListView list)
            {
                if (null == list)
                {
                    throw new ArgumentNullException();
                }

                _items = new List<MAFListViewItem>();
                NoteListView = list;
            }

            /// <summary>
            /// 拥有此集合的列表对象，由列表对象在内部传递this得到
            /// </summary>
            public MAFListView NoteListView { get; set; }

            /// <summary>
            /// 索引器
            /// </summary>
            /// <param name="index"></param>
            /// <returns></returns>
            public MAFListViewItem this[int index]
            {
                get { return _items[index]; }
            }

            /// <summary>
            /// 增加列表项
            /// </summary>
            /// <param name="item"></param>
            public int Add(MAFListViewItem item)
            {
                NoteListView.Controls.Add(item);        // 加到Controls集合，以便显示
                _items.Add(item);                       // 记住通过本集合增加的Controls

                item.Width = this.NoteListView.Width;   // 设置宽度
                item.Height = 50;
                item.Anchor = AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom | AnchorStyles.Left;
                var i = _items.IndexOf(item);           // 获取索引
                if (0 < i)                              // 设置当前列表项的位置
                {
                    var pItem = _items[i - 1];
                    var location = pItem.Location;
                    item.Location = new Point(location.X, location.Y + pItem.Height + 6);
                }
                item.Click += new EventHandler(NoteListView.OnItemClick);

                return i;
            }

            /// <summary>
            /// 重载，增加列表项
            /// </summary>
            /// <param name="s"></param>
            public int Add(string s)
            {
                return Add(new MAFListViewItem(s));
            }

            /// <summary>
            /// 删除列表项
            /// </summary>
            /// <param name="item"></param>
            public void Remove(MAFListViewItem item)
            {
                NoteListView.Controls.Remove(item);
            }

            /// <summary>
            /// 清除所有列表项
            /// </summary>
            public void Clear()
            {
                foreach (var item in _items)
                {
                    NoteListView.Controls.Remove(item);
                }
                _items.Clear();
            }
        }

        #endregion

        #region 事件

        /// <summary>
        /// 列表项点击事件
        /// </summary>
        public event EventHandler ItemClick;

        /// <summary>
        /// 此事件必须在IsShowCheck属性为True时才起作用
        /// </summary>
        public event EventHandler ItemCheckStateChanged;

        /// <summary>
        /// 列表项勾选状态改变
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void OnItemCheckStateChanged(object sender, EventArgs e)
        {
            var chk = sender as CheckBox;
            //if (chk.Checked)
            //CheckedItems.Add(chk.Parent as NoteListViewItem);
            //else
            //CheckedItems.Remove(chk.Parent as NoteListViewItem);

            if (null != ItemCheckStateChanged)
                ItemCheckStateChanged(sender, e);
        }

        /// <summary>
        /// 列表项被点击
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void OnItemClick(object sender, EventArgs e)
        {
            if (null != ItemClick)
                ItemClick(sender, e);
        }
        #endregion
    }

    /// <summary>
    /// 列表项
    /// </summary>
    public class MAFListViewItem : UserControl
    {
        /// <summary>
        /// CheckBox属性
        /// </summary>
        public CheckBox Check { get; private set; }

        /// <summary>
        /// 是否显示CheckBox
        /// </summary>
        public bool IsShowCheck { get; set; }

        /// <summary>
        /// 构造方法
        /// </summary>
        public MAFListViewItem()
            : this(string.Empty)
        {
        }

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="text"></param>
        public MAFListViewItem(string text)
        {
            InitializeComponent();
            this.Text = text;
        }

        /// <summary>
        /// 初始化组件
        /// </summary>
        private void InitializeComponent()
        {
            this.SuspendLayout();
            // 
            // NoteListView
            // 
            this.Check = new CheckBox();
            this.Check.Width = 20;
            this.Check.Parent = this;
            this.Controls.Add(this.Check);
            this.IsShowCheck = false;
            this.Check.Visible = IsShowCheck;
            this.Check.Location = new Point(0, 0);
        }

        /// <summary>
        /// 重绘
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics g = e.Graphics;
            var pen = Pens.Black;
            var brush = Brushes.Black;

            // 为窗体画边框，注意1像素问题
            var _rect = GetRectangle();
            var rect = new Rectangle(_rect.X, _rect.Y, _rect.Width - 1, _rect.Height - 1);
            g.DrawRectangle(pen, rect);

            // 展示文字
            DrawString(g);
        }

        /// <summary>
        /// 展示文字
        /// </summary>
        /// <param name="g"></param>
        private void DrawString(Graphics g)
        {
            var pen = new Pen(this.ForeColor);
            var brush = new SolidBrush(this.ForeColor);

            //var len = g.MeasureString(this.Text,this.Font);
            //var rowCount = len.Width/(float)this.Width;

            // 为文字和边框之间留下6像素空隙
            var _rect = GetRectangle();
            var rect = new Rectangle(_rect.X + 6, _rect.Y + 6, _rect.Width - 6, _rect.Height - 6);
            g.DrawString(this.Text, this.Font, brush, rect);
        }

        /// <summary>
        /// 获取基本矩形
        /// </summary>
        /// <returns></returns>
        private Rectangle GetRectangle()
        {
            var checkBoxWidth = 0;
            if (IsShowCheck)
            {
                checkBoxWidth = this.Check.Width;
                this.Check.Visible = true;
            }
            else
            {
                this.Check.Visible = false;
            }
            return new Rectangle(checkBoxWidth, 0, this.Width - checkBoxWidth, this.Height);
        }
    }
}
